package com.shyroke.daydayzhuanshiro.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 类名 ：shiro的核心配置类
 * 用法 ：
 * 创建人 ： shyroke
 * 时间：2018/12/14 15:20
 */
@Configuration
public class ShiroConfigration {

//    设置自定义Realm
    @Bean
    public MyRealm myRealm(){
        return new MyRealm();
    }

//    权限管理，配置主要是Realm的管理认证
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(myRealm());
        manager.setSessionManager(this.sessionManager());
        return manager;
    }


    @Bean(name = "sessionManager")
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 设置session过期时间7天
        sessionManager.setGlobalSessionTimeout(7 * 24 * 60 * 60 * 1000);
        return sessionManager;
    }

    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

    /**
     * 设置过滤条件和跳转条件
     * anon 不生效的原因：1、map的类型必须是LinkedHashMap 2、anon必须定义在authc之前
     *
     * @param securityManager
     * @return
     */
    @Bean
        public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
            ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
            factoryBean.setSecurityManager(securityManager);

//            设置登录跳转
            factoryBean.setLoginUrl("/admin");
            factoryBean.setSuccessUrl("/admin/index");

            //必须为LinkedHashMap 否则anon不生效
            Map<String,String> map = new LinkedHashMap<>();

            //退出
            map.put("/admin/logout","logout");

            //登录页面和登录验证不要拦截
            map.put("/admin/login.html","anon");
            map.put("/admin/tologin","anon");
            map.put("/admin/register","anon");
            map.put("/admin/registerView","anon");
            map.put("/admin/project/uploadImg","anon");
            map.put("/api/**","anon");

            map.put("/robots.txt","anon");
            map.put("/ads.txt","anon");
            map.put("/urlPattern.txt","anon");
            map.put("/sitemap.xml","anon");
            map.put("/ByteDanceVerify.html","anon");

            //设置需要过滤的链接
            map.put("/admin/**","authc");


            factoryBean.setFilterChainDefinitionMap(map);

            return factoryBean;
        }


    /**
     *  开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可实现此功能
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    /**
     * 开启aop注解支持
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}
